package cn.jy.boot.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.security.web.util.matcher.OrRequestMatcher;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;

@Configuration
public class WebSecurityConfigurer extends WebSecurityConfigurerAdapter {




//    @Override
//    @Bean
//    public UserDetailsService userDetailsService(){
//
//        InMemoryUserDetailsManager inMemoryUserDetailsManager
//                = new InMemoryUserDetailsManager();
//        UserDetails u1 = User.withUsername("cl")
//                .password("{noop}123").roles("admin").build();
//        inMemoryUserDetailsManager.createUser(u1);
//        return inMemoryUserDetailsManager;
//    }

//    @Override
//    protected void configure(AuthenticationManagerBuilder builder) throws Exception {
//        builder.userDetailsService(userDetailsService());
//    }


    //系统默认
    //   springboot  全局的AuthenticationManager
// 默认的 AuthenticationManager

    @Override
    @Bean
    public UserDetailsService userDetailsService(){
        InMemoryUserDetailsManager userDetailsManager = new InMemoryUserDetailsManager();
        userDetailsManager.createUser(User.withUsername("fk").password("{noop}123").roles("admin").build());
        return userDetailsManager;
    }

//    @Autowired
//    public void initialize(AuthenticationManagerBuilder builder) throws Exception {
////  基于内存的
//        InMemoryUserDetailsManager userDetailsManager = new InMemoryUserDetailsManager();
//        userDetailsManager.createUser(User.withUsername("cl").password("{noop}123").roles("admin").build());
//        builder.userDetailsService(userDetailsManager);


//        InMemoryUserDetailsManager inMemoryUserDetailsManager
//                = new InMemoryUserDetailsManager();
//        UserDetails u1 = User.withUsername("cl")
//                .password("{noop}123").roles("admin").build();
//        inMemoryUserDetailsManager.createUser(u1);
//        builder.userDetailsService(inMemoryUserDetailsManager);
//    }



//    自定义全局的  AuthenticationManager 会默认覆盖

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {

        auth.userDetailsService(userDetailsService());
    }

    // 在工厂中暴露


    @Override
    @Bean
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
//        自定义配置
//        首页 不需要认证就可以访问  hello需要认证才能访问
        http.authorizeHttpRequests()
//               Can't configure mvcMatchers after anyRequest 放行资源必须放在认证请求之前
                .mvcMatchers("/","index").permitAll()
                .mvcMatchers("/static/**").permitAll()
                .mvcMatchers("/login.html").permitAll()//放行登录页面的请求
                .anyRequest().authenticated()
                .and()
                .formLogin()
                .loginPage("/login.html") //指定认证登录界面
                .loginProcessingUrl("/doLogin") //当指定了自定义的认证页面之后 一定要指定认证的地址
                .usernameParameter("uname").passwordParameter("pwd") //当表中参数的名字不是username和password时指定参数的名字
//                .defaultSuccessUrl("/index",true)
                //认证成功后 defaultSuccessUrl 重定向  默认如果在认证前访问了哪个受限的地址 就会转到哪个地址，
                // 设置了第二个参数为true后，无论如何都会跳转到 设置的地址
//                .successForwardUrl("/index")  //认证成功 转发的地址
//                .failureUrl("/login.html")//认证失败后 重定向的地址 session作用域拿取异常信息 SPRING_SECURITY_LAST_EXCEPTION
//                .failureForwardUrl("/login.html") //认证失败后 转发的地址  request作用域获取异常信息  SPRING_SECURITY_LAST_EXCEPTION
                // 前后端分离  成功之后的处理
                .successHandler(new MYAuthenticationSuccessHandler())
                // 前后端分离  失败之后的处理
                .failureHandler(new MyAuthenticationFailureHandler())
                .and()
                .logout()
//                .logoutUrl("/out") //注销地址 get请求
                .logoutRequestMatcher(new OrRequestMatcher(
                        new AntPathRequestMatcher("/out","GET"),
                        new AntPathRequestMatcher("/out1","POST")
                ))
                //前后端分离 注销
                .logoutSuccessHandler(new MyLogoutSuccessHandler())
                .invalidateHttpSession(true)  //session失效
                .clearAuthentication(true)   //清除认证的信息
                .and()
                .csrf().disable()  //跨域漏洞禁用掉
        ;
    }
}
